Scroll Progress Bar

Exceptions

In C++, exceptions are a powerful mechanism for handling unexpected or exceptional situations in code, such as runtime errors, exceptional conditions, or user-defined error scenarios. Exception handling allows to gracefully handle errors and prevent program from crashing. Here's an overview of exceptions in C++:

1. Throwing an Exception:

it can throw an exception using the throw keyword followed by an expression (typically an object) that represents the exception:

Program:

throw MyException("An error occurred.");
2. Catching an Exception:

To catch an exception and handle it, use try and catch blocks. The try block contains the code that might throw an exception, and the catch block specifies the type of exception to catch and handles it:

Program:

try {
    // Code that might throw an exception
    throw MyException("An error occurred.");
}
catch (const MyException& e) {
    // Handle the exception
    std::cerr << "Exception caught: " << e.what() << std::endl;
}
3. Handling Standard Exceptions:

C++ provides a set of standard exception classes in the <stdexcept> header, such as std::runtime_error, std::invalid_argument, and std::out_of_range. it can use these to handle common error conditions.

Program:

try {
    int x = 10;
    if (x < 0) {
        throw std::invalid_argument("x must be non-negative.");
    }
}
catch (const std::invalid_argument& e) {
    std::cerr << "Invalid argument: " << e.what() << std::endl;
}
4. Creating Custom Exceptions:

it can define custom exception classes by inheriting from std::exception or any of its derived classes and overriding the what() function to provide a description of the exception:

Program:

class MyException : public std::exception {
public:
    MyException(const char* message) : msg(message) {}
    const char* what() const noexcept override {
        return msg.c_str();
    }

private:
    std::string msg;
};
5. Rethrowing Exceptions:

it can rethrow exceptions to propagate them up the call stack:

Program:

try {
    // Code that might throw an exception
    throw MyException("An error occurred.");
}
catch (const MyException& e) {
    std::cerr << "Exception caught: " << e.what() << std::endl;
    // Rethrow the exception
    throw; // Re-throws the caught exception
}
6. Cleanup with finally (C++17 and later):

In C++17 and later, it can use finally blocks with the help of the std::uncaught_exceptions function to perform cleanup operations regardless of whether an exception was thrown or not.

Program:

try {
    // Code that might throw an exception
}
catch (const MyException& e) {
    std::cerr << "Exception caught: " << e.what() << std::endl;
}
finally {
    // Cleanup code (C++17 and later)
}
7. Standard Exceptions Hierarchy:

C++ provides a hierarchy of standard exception classes that it can be used for various types of errors. These are derived from std::exception. it can catch exceptions at different levels of the hierarchy to handle them selectively.

Program:

try {
    // Code that might throw an exception
}
catch (const std::exception& e) {
    std::cerr << "Exception caught: " << e.what() << std::endl;
}

Exception handling in C++ is a powerful mechanism for building robust and reliable software. It allows to gracefully handle errors and recover from exceptional situations while keeping code organized and maintainable.

A sample code with sample output using exception cases

Program:

#include <iostream>
#include <stdexcept>

// Custom exception class
class MyException : public std::exception {
public:
    MyException(const char* message) : msg(message) {}
    const char* what() const noexcept override {
        return msg.c_str();
    }

private:
    std::string msg;
};

int main() {
    try {
        // Exception case 1: Division by zero
        int numerator = 10;
        int denominator = 0;
        if (denominator == 0) {
            throw std::runtime_error("Division by zero.");
        }

        // Exception case 2: Using a custom exception
        int age = -5;
        if (age < 0) {
            throw MyException("Age it cannot be negative.");
        }

        // Exception case 3: Out of range
        int array[5] = {1, 2, 3, 4, 5};
        int index = 10;
        if (index < 0 || index >= 5) {
            throw std::out_of_range("Index is out of range.");
        }
    }
    catch (const std::runtime_error& e) {
        std::cerr << "Runtime Error: " << e.what() << std::endl;
    }
    catch (const MyException& e) {
        std::cerr << "Custom Exception: " << e.what() << std::endl;
    }
    catch (const std::out_of_range& e) {
        std::cerr << "Out of Range Exception: " << e.what() << std::endl;
    }
    catch (const std::exception& e) {
        std::cerr << "Generic Exception: " << e.what() << std::endl;
    }
    catch (...) {
        std::cerr << "Unknown Exception" << std::endl;
    }

    std::cout << "Program continues after exception handling." << std::endl;

    return 0;
}
Sample Output:

Runtime Error: Division by zero.
Program continues after exception handling.
In this example:
Three exception cases:
  • Division by zero using std::runtime_error.
  • Using a custom exception MyException for negative age.
  • Index out of range using std::out_of_range.
  • Each exception case is handled in a separate catch block, and a generic catch block is included to catch any other exceptions. The catch-all block catch (...) is used to catch any exceptions that are not explicitly handled.

After handling exceptions, the program continues to execute, demonstrating how exceptions allow to gracefully recover from errors without crashing the program.

This example shows how to use standard exceptions and custom exceptions to handle different types of exceptional situations in code.


question


answer

question2


answer2